package org.javaboy.spring_cache_redis.service;

import org.javaboy.spring_cache_redis.model.User;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
/**
 * 可以在 @CacheConfig 注解中配置缓存的名称，这样就不需要在具体的缓存注解中配置缓存名称了
 */
@CacheConfig(cacheNames = "user")
public class UserService {

    /**
     * 根据 id 查询用户信息
     *
     * @param id
     * @return
     * @Cacheable 注解表示将方法的返回值缓存起来，默认行为是缓存的 key 是方法参数的值，缓存的 value 是方法的返回值
     * <p>
     * #id 表示只使用 id 这个参数作为缓存的 key
     * #root.method.name 表示使用方法名作为 key
     */
    @Cacheable/*(cacheNames = "user")*/
    public User getUserById(Integer id) {
        System.out.println("getUserById>>>" + id);
        User user = new User();
        user.setId(id);
        return user;
    }


    /**
     * 更新用户信息
     * @CachePut 注解表示更新缓存，更新的时候，也是以方法的参数作为更新缓存的 key。
     * 想要更新缓存生效，就需要确保更新缓存的 key 和查询缓存的 key 是一致的
     *
     * 需要注意，如果使用了 @CachePut 注解，那么方法的返回值就不能是 void 了，否则就不会更新数据了
     * @param id
     * @return
     */
    @CachePut/*(cacheNames = "user")*/
    public User updateUserById(Integer id) {
        //去数据库做更新操作
        System.out.println("updateUserById>>>" + id);
        //更新缓存中的数据
        User user = new User();
        user.setId(id);
        user.setName("update");
        //返回更新后的数据，就会自动更新缓存中的数据
        return user;
    }

    /**
     * 删除用户信息
     * 去数据库中删除数据的时候，也要同时删除缓存中的数据
     *
     * allEntries = true 表示删除缓存中所有的数据，默认是 false，表示只删除当前缓存的数据（根据方法参数所对应的 key 去删除）
     * beforeInvocation = true 表示在方法执行之前删除缓存，默认是 false，即先删除缓存，再执行删除方法去数据库中删除数据，true 是在方法执行之后删除缓存
     * @param id
     */
    @CacheEvict/*(cacheNames = "user")*/
    public void deleteUserById(Integer id) {
        System.out.println("deleteUserById>>>" + id);
    }

}
